import { provide, inject, defineComponent, createVNode, render, reactive, computed, onMounted, onBeforeUnmount, ref } from "vue";

export const DropdownItem = defineComponent({
    props: {
        label: String,
        icon: String
    },
    setup(props){
        const {icon, label} = props
        let hide  = inject('hide')
        return () => <div class='dropdown-item' onClick={hide}>
            <i class={icon}>{}</i>
            <span>{label}</span>
        </div>

    }
})

const DropdownComponent = defineComponent({
    props: {
        option: {type: Object}
    },
    setup(props, ctx){
        const state = reactive({
            option: props.option,
            isShow: false,
            top: 0,
            left: 0,
        })
        ctx.expose({ // 让外界可以调用组件内部的方法
            showDropdown(option){
                state.option = option
                state.isShow = true
                let {top, left, height} = option.el.getBoundingClientRect()
                state.top = top +height
                state.left = left
            }
        })

        provide('hide', () => {
            state.isShow = false
        })

        const classes = computed(() => [
            'dropdown',
            {
                'dropdown-is-show': state.isShow
            }
        ])

        const styles = computed(() => ({
            top: state.top+'px',
            left: state.left+'px'
        }))

        const el = ref(null)

        const onMousedownDocument = (e) => {
            if(!el.value.contains(e.target)){
                state.isShow = false
            }
        }

        onMounted(() => {
            document.body.addEventListener('mousedown', onMousedownDocument, true)
        })

        onBeforeUnmount(() => {
            document.body.removeEventListener('mousedown', onMousedownDocument)
        })

        return () => {
            return <div class={classes.value} style={styles.value} ref={el}>{
                state.option.content()
            }</div>
        }
    }
})

let vm

export function $dropdown(option) {
    if(!vm){
        let el = document.createElement('div')
        vm = createVNode(DropdownComponent, {option}) // 将组建渲染成虚拟节点
        document.body.appendChild((render(vm, el), el)) // 渲染成真实节点 扔到dom中去
    }
    let { showDropdown } = vm.component.exposed
    showDropdown(option)
}
